home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / python / autodler.py < prev    next >
Encoding:
Python Source  |  2007-11-12  |  6.8 KB  |  193 lines

  1. # Miro - an RSS based video player application
  2. # Copyright (C) 2005-2007 Participatory Culture Foundation
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  17.  
  18. import filters
  19. import views
  20. import config
  21. import prefs
  22. import eventloop
  23. import httpclient
  24. from clock import clock
  25. from datetime import datetime
  26. from fasttypes import SortedList
  27.  
  28. # filter functions we use to create views.
  29.  
  30. def manualPendingFilter(x):
  31.     """Returns true iff x is a manual download item that's pending"""
  32.     return x.isPendingManualDownload()
  33.  
  34. def autoPendingFilter(x):
  35.     """Returns true iff x is an automatic download item that's pending"""
  36.     if not x.getFeed().isAutoDownloadable ():
  37.         return False
  38.     return x.isEligibleForAutoDownload()
  39.  
  40. def pendingSort(a, b):
  41.     if a[1] < b[1]:
  42.         return True
  43.     if a[1] > b[1]:
  44.         return False
  45.     return a[2] < b[2]
  46.  
  47. class Downloader:
  48.     def __init__ (self, is_auto):
  49.         self.dc = None
  50.         self.inDownloads = False
  51.         self.paused = False
  52.         self.running_count = 0
  53.         self.pending_count = 0
  54.         self.feed_pending_count = {}
  55.         self.feed_running_count = {}
  56.         self.feed_time = {}
  57.         self.is_auto = is_auto
  58.         if is_auto:
  59.             self.pendingItems = views.items.filter (autoPendingFilter)
  60.             self.runningItems = views.autoDownloads
  61.             self.MAX = config.get(prefs.DOWNLOADS_TARGET)
  62.         else:
  63.             self.pendingItems = views.items.filter (manualPendingFilter)
  64.             self.runningItems = views.manualDownloads
  65.             self.MAX = config.get(prefs.MAX_MANUAL_DOWNLOADS)
  66.  
  67.         for item in self.pendingItems:
  68.             self.pendingOnAdd(item, item.id)
  69.         for item in self.runningItems:
  70.             self.runningOnAdd(item, item.id)
  71.         self.pendingItems.addAddCallback(self.pendingOnAdd)
  72.         self.pendingItems.addRemoveCallback(self.pendingOnRemove)
  73.         self.runningItems.addAddCallback(self.runningOnAdd)
  74.         self.runningItems.addRemoveCallback(self.runningOnRemove)
  75.  
  76.         if is_auto:
  77.             self.new_count = 0
  78.             self.feed_new_count = {}
  79.             self.newItems = views.newlyDownloadedItems
  80.             for item in self.newItems:
  81.                 self.newOnAdd(item, item.id)
  82.             self.newItems.addAddCallback(self.newOnAdd)
  83.             self.newItems.addRemoveCallback(self.newOnRemove)
  84.  
  85.     def updateMAX(self):
  86.         if self.is_auto:
  87.             newmax = config.get(prefs.DOWNLOADS_TARGET)
  88.         else:
  89.             newmax = config.get(prefs.MAX_MANUAL_DOWNLOADS)
  90.         if newmax != self.MAX:
  91.             self.MAX = newmax
  92.             self.startDownloads()
  93.  
  94.     def startDownloadsIdle(self):
  95.         if self.paused:
  96.             return
  97.         last_count = 0
  98.         while self.running_count < self.MAX and self.pending_count > 0 and self.pending_count != last_count:
  99.             last_count = self.pending_count
  100.             sorted = SortedList (pendingSort)
  101.             for feed in views.feeds:
  102.                 if self.is_auto:
  103.                     max_new = feed.getMaxNew()
  104.                     if max_new != "unlimited" and max_new <= self.feed_new_count.get(feed, 0) + self.feed_running_count.get(feed, 0):
  105.                         continue
  106.                 if self.feed_pending_count.get(feed, 0) <= 0:
  107.                     continue
  108.                 sorted.append ((feed, self.feed_running_count.get(feed, 0), self.feed_time.get(feed, datetime.min)))
  109.             for feed, count, time in sorted:
  110.                 if self.is_auto:
  111.                     feed.startAutoDownload()
  112.                 else:
  113.                     feed.startManualDownload()
  114.                 self.feed_time[feed] = datetime.now()
  115.                 if self.running_count >= self.MAX:
  116.                     break
  117.         self.dc = None
  118.  
  119.     def startDownloads(self):
  120.         if self.dc or self.paused:
  121.             return
  122.         self.dc = eventloop.addIdle(self.startDownloadsIdle, "Start Downloads")
  123.  
  124.     def pendingOnAdd(self, obj, id):
  125.         feed = obj.getFeed()
  126.         self.pending_count = self.pending_count + 1
  127.         self.feed_pending_count[feed] = self.feed_pending_count.get(feed, 0) + 1
  128.         self.startDownloads()
  129.     
  130.     def pendingOnRemove(self, obj, id):
  131.         feed = obj.getFeed()
  132.         self.pending_count = self.pending_count - 1
  133.         self.feed_pending_count[feed] = self.feed_pending_count.get(feed, 0) - 1
  134.     
  135.     def runningOnAdd(self, obj, id):
  136.         feed = obj.getFeed()
  137.         self.running_count = self.running_count + 1
  138.         self.feed_running_count[feed] = self.feed_running_count.get(feed, 0) + 1
  139.     
  140.     def runningOnRemove(self, obj, id):
  141.         feed = obj.getFeed()
  142.         self.running_count = self.running_count - 1
  143.         self.feed_running_count[feed] = self.feed_running_count.get(feed, 0) - 1
  144.         self.startDownloads()
  145.     
  146.     def newOnAdd(self, obj, id):
  147.         feed = obj.getFeed()
  148.         self.new_count = self.new_count + 1
  149.         self.feed_new_count[feed] = self.feed_new_count.get(feed, 0) + 1
  150.     
  151.     def newOnRemove(self, obj, id):
  152.         feed = obj.getFeed()
  153.         self.new_count = self.new_count - 1
  154.         self.feed_new_count[feed] = self.feed_new_count.get(feed, 0) - 1
  155.         self.startDownloads()
  156.  
  157.     def pause(self):
  158.         if self.dc:
  159.             self.dc.cancel()
  160.             self.dc = None
  161.         self.paused = True
  162.  
  163.     def resume(self):
  164.         if self.paused:
  165.             self.paused = False
  166.             eventloop.addTimeout (5, self.startDownloads, "delayed start downloads")
  167.  
  168.  
  169. manualDownloader = None
  170. autoDownloader = None
  171.  
  172. def startDownloader():
  173.     global manualDownloader
  174.     global autoDownloader
  175.     manualDownloader = Downloader(False)
  176.     autoDownloader = Downloader(True)
  177.  
  178. def pauseDownloader():
  179.     manualDownloader.pause()
  180.     autoDownloader.pause()
  181.  
  182. def resumeDownloader():
  183.     manualDownloader.resume()
  184.     autoDownloader.resume()
  185.  
  186. def _updatePrefs(key, value):
  187.     if key == prefs.DOWNLOADS_TARGET.key:
  188.         autoDownloader.updateMAX()
  189.     elif key == prefs.MAX_MANUAL_DOWNLOADS.key:
  190.         manualDownloader.updateMAX()
  191.  
  192. config.addChangeCallback (_updatePrefs)
  193.